package com.meilishuo.message.aop;

import lombok.extern.log4j.Log4j;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.alibaba.fastjson.JSON;
import com.meilishuo.message.entity.common.GeneralResult;
import com.meilishuo.message.exceptions.AccessException;
import com.meilishuo.message.exceptions.BadRequestException;
import com.meilishuo.message.exceptions.ResourceNotFoundException;
import com.meilishuo.message.exceptions.ServiceException;
import com.meilishuo.message.exceptions.WarningException;


@Log4j
@ControllerAdvice
public class ApiExceptionHandler {
	
	//请求参数参数异常处理
	@ExceptionHandler(value = {BadRequestException.class, BindException.class, MethodArgumentNotValidException.class})
	@ResponseStatus(value = HttpStatus.BAD_REQUEST)
	@ResponseBody
	public GeneralResult handleBadRequestException(Exception e){
		return GeneralResult.newBuilder().setException(e).getResponse();
	}
	
	//未授权异常处理
	@ExceptionHandler(value={AccessException.class})
	@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
	@ResponseBody
	public GeneralResult handleAccessException(AccessException e){
		return GeneralResult.newBuilder().setException(e).getResponse();
	}
	
	//业务逻辑异常处理
	@ExceptionHandler(value={ServiceException.class})
	@ResponseStatus(value = HttpStatus.OK)
	@ResponseBody
	public GeneralResult handleBaseException(ServiceException e){
		return GeneralResult.newBuilder().setException(e).getResponse();
	}
	
	//资源不存在异常处理
	@ExceptionHandler(value = {ResourceNotFoundException.class})
	@ResponseStatus(value = HttpStatus.NOT_FOUND)
	@ResponseBody
	public GeneralResult handleResourceNotFoundException(ResourceNotFoundException e){
		return GeneralResult.newBuilder().setException(e).getResponse();
	}
	
	/**
	 * 开发阶段异常提醒
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = {WarningException.class})
	@ResponseStatus(value = HttpStatus.OK)
	@ResponseBody
	public GeneralResult handleWarningException(WarningException e){
		return GeneralResult.newBuilder().setException(e).getResponse();
	}
	
	//未知异常处理
	@ExceptionHandler(value = {Exception.class})
	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
	@ResponseBody
	public GeneralResult handleUnknowException(Exception e){
		log.error(JSON.toJSONString(e));
		return GeneralResult.newBuilder().setException(e).getResponse();
	}
	
}

//GET
//- 获取表示
//- 变更时获取表示（缓存）
//200（OK） - 表示已在响应中发出
//204（无内容） - 资源有空表示
//301（Moved Permanently） - 资源的URI已被更新
//303（See Other） - 其他（如，负载均衡）
//304（not modified）- 资源未更改（缓存）
//400 （bad request）- 指代坏请求（如，参数错误）
//404 （not found）- 资源不存在
//406 （not acceptable）- 服务端不支持所需表示
//500 （internal server error）- 通用错误响应
//503 （Service Unavailable）- 服务端当前无法处理请求
//
//
//DELETE
//- 删除资源
//200 （OK）- 资源已被删除
//301 （Moved Permanently）- 资源的URI已更改
//303 （See Other）- 其他，如负载均衡
//400 （bad request）- 指代坏请求t
//404 （not found）- 资源不存在
//409 （conflict）- 通用冲突
//500 （internal server error）- 通用错误响应
//503 （Service Unavailable）- 服务端当前无法处理请求
//
//
//PUT
//- 用客户端管理的实例号创建一个资源
//- 通过替换的方式更新资源
//- 如果未被修改，则更新资源（乐观锁）
//200 （OK）- 如果已存在资源被更改
//201 （created）- 如果新资源被创建
//301（Moved Permanently）- 资源的URI已更改
//303 （See Other）- 其他（如，负载均衡）
//400 （bad request）- 指代坏请求
//404 （not found）- 资源不存在
//406 （not acceptable）- 服务端不支持所需表示/p>
//409 （conflict）- 通用冲突
//412 （Precondition Failed）- 前置条件失败（如执行条件更新时的冲突）
//415 （unsupported media type）- 接受到的表示不受支持
//500 （internal server error）- 通用错误响应
//503 （Service Unavailable）- 服务当前无法处理请求
//
//
//POST
//- 使用服务端管理的（自动产生）的实例号创建资源
//- 创建子资源
//- 部分更新资源
//- 如果没有被修改，则不过更新资源（乐观锁）
//200（OK）- 如果现有资源已被更改
//201（created）- 如果新资源被创建
//202（accepted）- 已接受处理请求但尚未完成（异步处理）
//301（Moved Permanently）- 资源的URI被更新
//303（See Other）- 其他（如，负载均衡）
//400（bad request）- 指代坏请求
//404 （not found）- 资源不存在
//406 （not acceptable）- 服务端不支持所需表示
//409 （conflict）- 通用冲突
//412 （Precondition Failed）- 前置条件失败（如执行条件更新时的冲突）
//415 （unsupported media type）- 接受到的表示不受支持
//500 （internal server error）- 通用错误响应
//503 （Service Unavailable）- 服务当前无法处理请求